package mdt.figure;

import org.tigris.gef.presentation.Fig;
import org.tigris.gef.presentation.FigRect;
import mdt.model.IMDTComment;
import mdt.model.INodeModel;

import java.awt.*;
import java.util.Iterator;

/**
 * Created by lambert on 2016/6/20.
 */
public class FigArrowText extends FigNodeEditable{
	private FigRect boundryFig;
	public static final int MIN_ARROW_WIDTH = 10;
	public static final int MIN_ARROW_HEIGHT = 25;
	private int arrowWidth = 30;
	private int arrowHeight = 40;

	public static final long serialVersionUID = 1l;

	public FigArrowText(IMDTComment owner) {
		super(owner, TextType.SINGLE_LINE);

		Dimension dim = getMinimumSize();
		boundryFig = new FigRect(0, 0, (int)dim.getWidth(), (int)dim.getHeight());
		boundryFig.setLineWidth(0);
		boundryFig.setVisible(true);
		addFig(boundryFig);
		setFilled(true);
		setOwner(owner);
	}

	public void setOwner(Object owner) {
		super.setOwner(owner);
		if (boundryFig != null)
			this.bindPort(owner, boundryFig);
	}

	public void setLineWidth(int w) {
		super.setLineWidth(w);
		boundryFig.setLineWidth(0);
		figText.setLineWidth(0);
	}

	public FigArrowText cloneFig() {
		FigArrowText cloned = (FigArrowText)super.cloneFig();
		java.util.List<Fig> figs =  getFigs();
		int idx = figs.indexOf(boundryFig);
		cloned.boundryFig = (FigRect)cloned.getFigAt(idx);
		return cloned;
	}

	public int getArrowWidth() {
		return arrowWidth;
	}

	public void setArrowWidth(int arrowWidth) {
		this.arrowWidth = arrowWidth;
	}

	public int getArrowHeight() {
		return arrowHeight;
	}

	public void setArrowHeight(int arrowHeight) {
		this.arrowHeight = arrowHeight;
	}

	public boolean isDragConnectable() {
		return false;
	}

	public Dimension getMinimumSize() {
		Dimension size = figText.getMinimumSize();
		size.width += arrowWidth * 2;
		size.height = Math.max(size.height, MIN_ARROW_HEIGHT);
		return size;
	}

	public void setFilled(boolean f) {
		super.setFilled(f);
		boundryFig.setFilled(false);
	}

	public void paint(Graphics g) {

		Polygon poly = new Polygon();
		for (Point p : getPoints()) {
			poly.addPoint(p.x, p.y);
		}

		//fill
		if (isFilled() && getFillColor() != null) {
			fillPolygon(g, poly);
		}
		super.paint(g);

		//draw polyline
		if (getLineWidth() > 0 && getLineColor() != null) {
			drawPolyline(g, poly);
		}


	}
	protected void setBoundsImpl(int x, int y, int w, int h) {
		Rectangle oldBounds = getBounds();
		Dimension dim = getMinimumSize();
		w = Math.max(w, dim.width);
		h = Math.max(h, dim.height);
		arrowHeight = h;
		boundryFig.setBounds(new Rectangle(x, y, w, h));
		figText.updateBounds(); //ensure minimum size
		figText.setBounds(new Rectangle(x + arrowWidth,
				y + (arrowHeight - figText.getHeight()) / 2,
				w - 2 * arrowWidth,
				figText.getHeight()));

		calcBounds(); // _x = x; _y = y; _w = w; _h = h;
		firePropChange("bounds", oldBounds, getBounds());
		updateEdges();
	}

	protected void initTextFig(INodeModel model) {
		super.initTextFig(model);
		figText.setLineWidth(0);
		figText.setTopMargin(2);
		figText.setBotMargin(2);
		figText.setLeftMargin(2);
		figText.setRightMargin(2);
		figText.setJustificationByName("Center");
		//figText.setEnableArc(true);
	}

	public void appendSvg(StringBuffer sb) {
		sb.append("<g id='").append(getId()).append("' class='").append(
				getClass().getName()).append("'>");
		sb.append("<g id='").append(getId() + ".g0'");
		appendSvgStyle(sb);
		sb.append(">");
		for (Iterator it = getFigs().iterator(); it.hasNext();) {
			Fig fig = (Fig) it.next();
			if (fig == figText) continue;
			fig.appendSvg(sb);
		}
		sb.append("<polygon id='" + getId() + "' points='");

		for (Point p : getPoints()) {
			sb.append(p.x + "," + p.y + " ");
		}
		sb.append("' ");

		appendSvgStyle(sb);
		sb.append(" />");
		sb.append("</g>");
		figText.appendSvg(sb);
		sb.append("</g>");
	}

	public Point[] getPoints() {
		int gap = (arrowHeight - figText.getHeight()) / 2;
		return new Point[] {
				new Point(_x + arrowWidth, _y),
				new Point(_x, _y + arrowHeight/2),
				new Point(_x + arrowWidth, _y + arrowHeight),
				new Point(_x + arrowWidth, _y + arrowHeight - gap),
				new Point(_x + _w - arrowWidth, _y + arrowHeight - gap),
				new Point(_x + _w - arrowWidth, _y + arrowHeight),
				new Point(_x + _w, _y + arrowHeight / 2),
				new Point(_x + _w - arrowWidth, _y),
				new Point(_x + _w - arrowWidth, _y + gap),
				new Point(_x + arrowWidth, _y + gap),
				new Point(_x + arrowWidth, _y),
		};
	}


}
